package com.lfy.modules.scheduler.service.impl;

import com.lfy.domain.entity.JobEntity;
import com.lfy.domain.entity.JobNoCreateVO;
import com.lfy.mapper.TaskMapper;
import com.lfy.domain.anno.Describe;
import com.lfy.domain.entity.JobTaskListVO;
import com.lfy.domain.enums.JobStatusEnum;
import com.lfy.modules.scheduler.service.TaskService;
import com.lfy.utils.TaskUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
@SuppressWarnings("unchecked")
public class TaskServiceImpl implements TaskService {
    @Resource
    private TaskMapper taskMapper;
    @Resource
    private Scheduler scheduler;
    @Override
    /**
     * 获取已创建的任务列表
     */
    public List<JobTaskListVO> getTaskList() {
        List<JobTaskListVO> taskList = taskMapper.getTaskList();
        return taskList.stream().map(item->{
            try {
                if(item.getJobTrigger()!= null && item.getJobTriggerGroup()!= null){
                    Trigger.TriggerState triggerState = scheduler.getTriggerState(TriggerKey.triggerKey(item.getJobTrigger(),item.getJobTriggerGroup()));
                    if(Objects.nonNull(triggerState)){
                        item.setJobStatus(JobStatusEnum.getValueByKey(triggerState.name()));
                    }else {
                        item.setJobStatus(JobStatusEnum.STATE_ONCE.getValue());
                    }
                }else {
                    item.setJobStatus(JobStatusEnum.STATE_ONCE.getValue());
                }
            } catch (SchedulerException e) {
                log.warn("in com.lfy.service.impl.taskServiceImpl() error trigger:{}",item.getJobTrigger());
            }
            String jobClassName = item.getJobClassName();
            try {
                log.info(jobClassName);
                Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(jobClassName.trim());
                String value = getAnnotationValue(jobClass);
                item.setJobDesc(value);
            } catch (Exception e) {
                log.warn("in com.lfy.service.impl.taskServiceImpl() getTaskDes error ");
            }
            return item;
        }).collect(Collectors.toList());

    }


    private static String getAnnotationValue(Class<? extends Job> jobClass) {
        Describe annotation = jobClass.getAnnotation(Describe.class);
        if (Objects.nonNull(annotation)) {
            return annotation.value();
        }
        return "未知任务";

    }
    /**
     * 获取未创建的任务列表
     * @return List
     */
    @Override
    public List<JobNoCreateVO> getNoCreateTask() {
        //获取所有Job任务
        Set<String> classCache = TaskUtil.getClassInCache();
        if(CollectionUtils.isEmpty(classCache)){
            return null;
        }
        //获取已创建的任务
        List<String> jobList = taskMapper.getJobList().stream().map(JobEntity::getJobClassName).collect(Collectors.toList());
        //过滤出未创建的任务
        Set<String> filterSet = classCache.stream().filter(item -> !jobList.contains(item)).collect(Collectors.toSet());
        if(CollectionUtils.isEmpty(filterSet)){
            return null;
        }
        for (String s : filterSet) {
            System.out.println(s);
        }
        return filterSet.stream().map(item -> {
            JobNoCreateVO jobNoCreateVO = new JobNoCreateVO();
            try {
                Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(item);
                String annotationValue = getAnnotationValue(jobClass);
                jobNoCreateVO.setJobDesc(annotationValue);

                jobNoCreateVO.setJobClass(item);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return jobNoCreateVO;
        }).collect(Collectors.toList());
    }

    /**
     * 查找所有Job的全限定类名
     */
    @PostConstruct
    private void findJobClasses() {
        ClassPathScanningCandidateComponentProvider classPathScanningCandidateComponentProvider = new ClassPathScanningCandidateComponentProvider(false);
        classPathScanningCandidateComponentProvider.addIncludeFilter(new AssignableTypeFilter(Job.class));
        Set<BeanDefinition> candidateComponents = classPathScanningCandidateComponentProvider.findCandidateComponents("com.lfy");
        Set<String> allJob = candidateComponents.stream().map(BeanDefinition::getBeanClassName).collect(Collectors.toSet());
        TaskUtil.addClassInCache(allJob);
    }
}
